package com.hbpu.maven.spring.aop.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.*;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;

import java.util.Arrays;


/**
 * 日志切面类，用于记录方法执行的日志信息，包括方法开始、结束、异常和返回值。
 * 使用AOP技术拦截指定方法，并在不同执行阶段输出日志。
 */
@Order(1)
@Component
@Aspect
public class LogAspect {
    @Pointcut("execution(int com.hbpu.maven.spring.aop.calculator.MathCalculator.*(..))")
    public void pointcut() {
    }

    /**
     * 在匹配的方法执行前触发，记录方法名称和传入的参数。
     * 切点表达式匹配返回值为int且参数为两个int类型的方法。
     */
    @Before("pointcut()")
    public void logStart(JoinPoint joinPoint) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();
        System.out.println("[LogAspect] 开始执行方法：" + methodName + "，参数：" + Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * 在匹配的方法执行结束后触发，无论方法是否成功完成或抛出异常。
     * 用于记录方法执行结束的日志。
     */
    @After("pointcut()")
    public void logEnd() {
        System.out.println("[LogAspect] 结束");
    }

    /**
     * 在匹配的方法抛出异常时触发，记录异常信息和方法名称。
     * 切点表达式匹配返回值为int且参数为两个int类型的方法。
     */
    @AfterThrowing(value = "pointcut()", throwing = "e")
    public void logException(JoinPoint joinPoint, Exception e) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();
        System.out.println("[LogAspect] 异常：" + methodName + "方法抛出异常：" + e.getMessage());
    }

    /**
     * 在匹配的方法成功执行并返回结果后触发，记录方法名称和返回值。
     * 切点表达式匹配返回值为int且参数为两个int类型的方法。
     */
    @AfterReturning(value = "pointcut()", returning = "returnValue")
    public void logReturn(JoinPoint joinPoint, int returnValue) {
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String methodName = signature.getName();
        System.out.println("[LogAspect] 方法：" + methodName + "返回：" + returnValue);
    }

    /**
     * 在带有@UUID注解的方法执行前触发，用于处理与注解相关的逻辑。
     * 切点表达式匹配标注了@UUID注解的方法。
     */
    @Before("@annotation(com.hbpu.maven.spring.aop.annotation.UUID)")
    public void testAnnotation() {
        System.out.println("[LogAspect] 注解类型");
    }

    /**
     * （当前方法被注释）在方法参数标注了@UUID注解时触发，用于处理与参数注解相关的逻辑。
     * 切点表达式匹配参数标注了@UUID注解的方法。
     */
    //    @Before("@args(com.hbpu.maven.spring.aop.annotation.UUID)")
    public void testArgs() {
        System.out.println("[LogAspect] 参数类型");
    }

}
